package cn.virens.support;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.tio.core.ChannelContext;

import cn.virens.App;
import cn.virens.TCPServerHeartbeat;
import cn.virens.TioUtil;
import cn.virens.packet.DBPacket;
import cn.virens.packet.WritePacket;
import cn.virens.packet.factory.AbstractFactory;

public class TCPServerImplHeartbeat extends TCPServerImplDevice implements TCPServerHeartbeat {
	protected final Map<String, AbstractFactory> factoryMap = new ConcurrentHashMap<>();

	protected int heartidle;
	protected int heartTimer;
	protected int selectTime;

	public int getHeartidle() {
		return heartidle;
	}

	public void setHeartidle(int idleCount) {
		this.heartidle = idleCount;
	}

	public int getHeartTimer() {
		return heartTimer;
	}

	public void setHeartTimer(int heartbeatTimer) {
		this.heartTimer = heartbeatTimer;
	}

	public int getSelectTime() {
		return selectTime;
	}

	public void setSelectTime(int selectTime) {
		this.selectTime = selectTime;
	}

	public void addBuilder(String key, AbstractFactory builder) {
		this.factoryMap.put(key, builder);
	}

	@Override
	public String sendAll(DBPacket packet) {
		// 获取对应的包构造器
		AbstractFactory builder = factoryMap.get(packet.cmd());
		if (builder == null) return "ERROR_PACKET";

		this.channelForEach((channelContext) -> {
			WritePacket wpacket = builder.build(packet, channelContext, true);
			if (wpacket != null && TioUtil.write(channelContext, wpacket)) {
				// 已发送一个
			}
		});

		return "SUCCESS";
	}

	@Override
	public String sendQueue(DBPacket packet) {
		// 获取MAC对应的连接 & MAC设备类型
		ChannelContext channelContext = channelGet(packet.mac());
		if (channelContext == null) return "ERROR_DEVICE";

		// 获取对应的包构造器
		AbstractFactory builder = factoryMap.get(packet.cmd());
		if (builder == null) return "ERROR_PACKET";

		// 生成待发送数据帧
		WritePacket wpacket = builder.build(packet, channelContext, true);
		if (wpacket != null && TioUtil.write(channelContext, wpacket)) {
			return wpacket.seq() + "";
		} else {
			return "FAIL";
		}
	}

	@Override
	public void initialize() throws Exception {
		super.initialize();

		// 启动心跳检查定时器
		App.schedule(new ExecutorRunnableHeat(this, "心跳检查"), heartTimer);
		App.schedule(new SelectDataRunnableHeat(this, "查询数据"), selectTime);
	}
}
